home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-28 | 43.3 KB | 2,042 lines |
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i186: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part08/12
- Message-ID: <12977@xanth.cs.odu.edu>
- Date: 28 Jun 90 12:23:12 GMT
- Sender: news@cs.odu.edu
- Reply-To: Matt Dillon <@uunet.uu.net:overload!dillon>
- Lines: 2028
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
- Posting-number: Volume 90, Issue 186
- Archive-name: unix/uucp-1.06d/part08
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 8 (of 12)."
- # Contents: uucp2/src/getty/getty.c uucp2/src/uucico/gio.c
- # Wrapped by tadguy@xanth on Thu Jun 28 08:21:31 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'uucp2/src/getty/getty.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'uucp2/src/getty/getty.c'\"
- else
- echo shar: Extracting \"'uucp2/src/getty/getty.c'\" \(20766 characters\)
- sed "s/^X//" >'uucp2/src/getty/getty.c' <<'END_OF_FILE'
- X
- X/*
- X * GETTY.C
- X *
- X * $Header: Beta:src/uucp/src/getty/RCS/getty.c,v 1.1 90/02/02 12:13:30 dillon Exp Locker: dillon $
- X *
- X * (C)Copyright 1989, Matthew Dillon, All Rights Reserved
- X *
- X * Uses:
- X * GETTY:PASSWD
- X * GETTY:LOGFILE
- X * GETTY:Getty-Header
- X *
- X * GETTY <options> <modem-commands>
- X *
- X * -Sdevicenam Tells GETTY which serial.device to use, default
- X * serial.device
- X *
- X * -Uunitnum Tells GETTY which unit number to use, default 0
- X *
- X * -A Always talk to the modem at the first baud
- X * rate in the -B list and ignore the baud rate
- X * in the CONNECT message.
- X *
- X * -7 use SERF_7WIRE while online.
- X *
- X * -Bn Set baud rate. If specified multiple times the
- X * first one is the default and remaining ones
- X * switched to when a BREAK is received after a
- X * connect. Also determines how CONNECT messages
- X * are interpreted. A CONNECT with no number uses
- X * the first -B entry while CONNECTs with numbers
- X * use those numbers regardless of any -B entries.
- X *
- X * -Mc Set modem type:
- X * c = m = multimodem
- X * h = hays
- X * d = dumb (no AT or +++ cmds are ever sent),
- X * normally used with only one specified
- X * baud rate.
- X *
- X * -m1 Turn on the modem speaker during dialing/connect
- X * (default is -m0)
- X *
- X * -h0 Ignore CD (carrier detect), default is to use
- X * carrier detect.
- X *
- X * -c0 Ignore CONNECT message (i.e. you are not connected
- X * to a modem, usually combined with -h0). Default is
- X * to expect a CONNECT message.
- X *
- X * -d0 do not use DTR to drop connection. Default is
- X * to drop DTR to drop a connection. If this option
- X * is chosen the +++ and ATH0 sequence will be used
- X * to drop a connection.
- X *
- X * -xn Set debug level. Also causes log output to go
- X * to stdout instead of GETTY:LOGFILE
- X *
- X * -0 QUIT - Kills any running getty for the specified
- X * port.
- X *
- X * Any fields specified without a '-' are considered modem commands
- X * used to initialize/reinitialize the modem. Up to 16 fields may
- X * be specified (each is sent to the modem in 1 second intervals)
- X */
- X
- X#include <exec/types.h>
- X#include <exec/lists.h>
- X#include <exec/devices.h>
- X#include <devices/timer.h>
- X#include <devices/serial.h>
- X#include <libraries/dos.h>
- X#include <libraries/dosextens.h>
- X#include <hardware/cia.h>
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include "protos.h"
- X#include <pwd.h>
- X#include "version.h"
- X
- X#include "log.h"
- X
- XIDENT(".02");
- X
- X#ifndef IO_STATF_READBREAK
- X#define IO_STATF_READBREAK (IOSTF_READBREAK<<8)
- X#endif
- X
- X#define arysize(ary) (sizeof(ary)/sizeof((ary)[0]))
- X
- X#define ST_WAITCD 0
- X#define ST_CONNECT 1
- X#define ST_LOGIN 2
- X#define ST_PASSWD 3
- X#define ST_RUN 4
- X
- Xtypedef struct IORequest IOR;
- Xtypedef struct timerequest IOT;
- Xtypedef struct IOExtSer IOSER;
- Xtypedef struct MsgPort PORT;
- Xtypedef struct List LIST;
- Xtypedef struct Node NODE;
- Xtypedef struct Message MSG;
- Xtypedef void (*FPTR)();
- X
- Xtypedef struct GMsg {
- X struct Message Msg;
- X short Cmd;
- X long Data1;
- X void *Data2;
- X} GMsg;
- X
- Xextern struct ProcID *RunPasswdEntry();
- X
- Xchar *CopyRight = "(c)Copyright 1989, Matthew Dillon, All Rights Reserved\r\n";
- Xchar *ComPortName;
- X
- Xchar *DeviceName = "serial.device";
- Xlong DeviceUnit = 0;
- Xlong NullFH;
- Xchar SpeakerLevel = 0;
- Xchar AnswerRing = 2; /* default, answer on second ring */
- Xchar SpeakerOpt = 0;
- Xchar IgnoreCD = 0;
- Xchar IgnoreConnect = 0;
- Xchar IgnoreDTR = 0;
- Xchar BaudAdjust = 0;
- Xchar DropOnExit = 1;
- Xchar ModemType = 'h';
- Xchar ZeroOption = 0;
- Xchar Wire7 = 0; /* use 7 wire while online */
- Xchar Locked = 0; /* serial port is lcked */
- Xlong Bauds[16] = { 9600 }; /* up 16 baud rates */
- Xchar *AtFields[16];
- X
- XPORT *ComPort;
- XPORT *IoSink; /* Sink for IO reqs. */
- Xlong IoSinkMask;
- Xlong ComPortMask;
- X
- XIOT Iot; /* check-carrier */
- XIOSER Iosr; /* serial read-req */
- XIOSER Iosw; /* serial write-req */
- X
- Xchar IotIP; /* Iot0 in progress */
- Xchar IosrIP;
- X
- Xchar ScrBuf[256];
- Xchar ConnectBuf[64];
- Xchar LoginBuf[32];
- Xchar PasswdBuf[32];
- Xchar RxBuf[32];
- Xchar HaveConnectMsg;
- Xchar HaveLogin;
- Xchar HavePasswd;
- X
- Xshort State;
- Xshort Index;
- Xshort BIndex;
- X
- Xshort CountDown;
- Xshort GotOffPort;
- X
- Xvoid SerPuts();
- Xvoid Set7Wire();
- Xvoid xexit();
- Xvoid Disconnect();
- Xvoid ClearRecv();
- Xvoid InitModem();
- Xvoid SetParams();
- Xvoid DoOptions();
- Xvoid SerialOff();
- Xvoid InterceptDeviceVector();
- Xvoid RestoreDeviceVector();
- X
- Xbrk()
- X{
- X return(0);
- X}
- X
- Xmain(ac, av)
- Xchar *av[];
- X{
- X extern int IAmGetty;
- X char termCr = 1;
- X char termLf = 1;
- X
- X IAmGetty = 1; /* for LockSerialPort()/UnLockSerialPort() */
- X
- X puts(CopyRight);
- X fflush(stdout);
- X onbreak(brk);
- X
- X LogProgram = "Getty";
- X LogWho = LoginBuf;
- X LogFile = "Getty:LOGFILE";
- X PasswdFile = "Getty:Passwd";
- X
- X DoOptions(ac, av);
- X
- X IoSink = CreatePort(NULL, 0);
- X IoSinkMask = 1 << IoSink->mp_SigBit;
- X
- X ComPortName = malloc(strlen(DeviceName) + 20);
- X sprintf(ComPortName, "Getty.%s.%ld", DeviceName, DeviceUnit);
- X
- X Forbid();
- X if (ComPort = FindPort(ComPortName)) {
- X GMsg msg;
- X msg.Cmd = 'O';
- X msg.Data1 = ac;
- X msg.Data2 = (void *)av;
- X msg.Msg.mn_ReplyPort = IoSink;
- X PutMsg(ComPort, &msg.Msg);
- X WaitPort(IoSink);
- X Remove(&msg.Msg.mn_Node);
- X Permit();
- X puts("Options updated");
- X xexit(0);
- X }
- X ComPort = CreatePort(ComPortName, 0L);
- X Permit();
- X
- X ComPortMask = 1L << ComPort->mp_SigBit;
- X
- X NullFH = Open("NULL:", 1006);
- X if (NullFH == NULL) {
- X ulog(-1, "GETTY REQUIRES NULL: HANDLER!");
- X puts("Requires NULL: handler!");
- X xexit(1);
- X }
- X if (LogToStdout == 0) {
- X freopen("NULL:", "r", stdin);
- X freopen("NULL:", "w", stdout);
- X freopen("NULL:", "w", stderr);
- X }
- X
- X
- X /*
- X * Timer Device
- X */
- X
- X Iot.tr_node.io_Message.mn_ReplyPort = IoSink;
- X if (OpenDevice("timer.device", UNIT_VBLANK, &Iot, 0L)) {
- X Iot.tr_node.io_Device = NULL;
- X xexit(20);
- X }
- X Iot.tr_node.io_Command = TR_ADDREQUEST;
- X
- X /*
- X * SERIAL.DEVICE
- X */
- X
- X Iosr.IOSer.io_Message.mn_ReplyPort = IoSink;
- X Iosr.io_SerFlags = SERF_XDISABLED | SERF_7WIRE | SERF_RAD_BOOGIE | SERF_SHARED;
- X if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0L)) {
- X Iosr.IOSer.io_Device = NULL;
- X xexit(21);
- X }
- X
- X InterceptDeviceVector(Iosr.IOSer.io_Device);
- X
- X Iosw = Iosr;
- X
- X Iosw.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE | SERF_SHARED;
- X Iosw.io_ExtFlags = 0;
- X Iosw.io_Baud = Bauds[0];
- X Iosw.io_ReadLen = 8;
- X Iosw.io_WriteLen = 8;
- X Iosw.io_StopBits = 1;
- X
- X SetParams(&Iosw);
- X
- X /*
- X * Run Operation
- X */
- X
- X State = ST_WAITCD;
- X Iot.tr_time.tv_secs = 1;
- X Iot.tr_time.tv_micro= 0;
- X IotIP = 1;
- X SendIO(&Iot);
- X
- X InitModem();
- X
- X Signal(FindTask(NULL), IoSinkMask);
- X
- X for (;;) {
- X long mask;
- X IOR *ior;
- X GMsg *msg;
- X mask = Wait(SIGBREAKF_CTRL_C | IoSinkMask | ComPortMask);
- X
- X ulog(2, "State = %d", State);
- X
- X if (mask & SIGBREAKF_CTRL_C)
- X break;
- X
- X if (msg = (GMsg *)GetMsg(ComPort)) {
- X do {
- X switch(msg->Cmd) {
- X case 'O':
- X DoOptions(msg->Data1, msg->Data2);
- X break;
- X }
- X ReplyMsg((MSG *)msg);
- X if (ZeroOption)
- X xexit(0);
- X } while (msg = (GMsg *)GetMsg(ComPort));
- X if (State == ST_WAITCD && !GotOffPort)
- X Disconnect(0);
- X }
- X
- X while (ior = (IOR *)GetMsg(IoSink)) {
- X if (ior == (IOR *)&Iot) {
- X short diu;
- X
- X IotIP = 0;
- X Iot.tr_time.tv_secs = 1;
- X Iot.tr_time.tv_micro= 0;
- X
- X /*
- X * If OpenCnt > 1, disable all processing.
- X *
- X * When returns to <= 1 reset serial port.
- X */
- X
- X diu = DeviceInUse();
- X if (diu) {
- X if (GotOffPort == 0) {
- X ulog(-1, "Device in use");
- X if (Locked)
- X ulog(-1, "getting off port");
- X SerialOff();
- X GotOffPort = 1;
- X State = ST_WAITCD;
- X }
- X SendIO(&Iot);
- X IotIP = 1;
- X continue;
- X }
- X if (GotOffPort) {
- X if (Locked == 0) {
- X LockSerialPort(DeviceName, DeviceUnit);
- X Locked = 1;
- X }
- X GotOffPort = 0;
- X ulog(-1, "Getty resetting");
- X SendIO(&Iot);
- X IotIP = 1;
- X Disconnect(1);
- X continue;
- X }
- X if (State == ST_WAITCD)
- X SerialOff();
- X
- X if (State != ST_WAITCD && IosrIP == 0) {
- X if (Locked == 0)
- X LockSerialPort(DeviceName, DeviceUnit);
- X Locked = 1;
- X ulog(-1, "Serial Port Locked");
- X
- X Iosr.IOSer.io_Command = CMD_READ;
- X Iosr.IOSer.io_Data = (APTR)RxBuf;
- X Iosr.IOSer.io_Length = 1;
- X SendIO(&Iosr);
- X IosrIP = 1;
- X ulog(1, "Carrier, Getty getting on port");
- X }
- X
- X Iosw.IOSer.io_Command = SDCMD_QUERY;
- X DoIO(&Iosw);
- X if (IgnoreCD)
- X Iosw.io_Status &= ~CIAF_COMCD;
- X
- X /*
- X * If state connected and we loose carrier, disconnect.
- X *
- X * If state connected and timeout occurs disconnect.
- X */
- X
- X if (State != ST_WAITCD) {
- X if ((Iosw.io_Status & CIAF_COMCD) != 0) {
- X ulog(1, "Getty, Carrier lost");
- X Disconnect(0);
- X } else {
- X if (--CountDown == 0) {
- X ulog(1, "Getty, Timeout, Disconnecting");
- X Disconnect(1);
- X Iosw.io_Status |= CIAF_COMCD; /* for below */
- X }
- X }
- X }
- X
- X switch(State) {
- X case ST_WAITCD:
- X if ((Iosw.io_Status & CIAF_COMCD) == 0) {
- X State = ST_CONNECT;
- X CountDown = 60; /* allow 60 seconds */
- X ulog(-1, "Carrier Detect");
- X } else {
- X Iot.tr_time.tv_secs = 2;
- X }
- X break;
- X case ST_CONNECT:
- X /*
- X * Wait for CONNECT message, then send Login:
- X */
- X
- X if (IgnoreConnect && HaveConnectMsg == 0) {
- X if (Wire7)
- X Set7Wire(&Iosw);
- X HaveConnectMsg = 1;
- X ulog(-1, "Connect");
- X }
- X
- X if (HaveConnectMsg) {
- X FILE *fi;
- X
- X Delay(50);
- X ClearRecv();
- X if (fi = fopen("Getty:Getty-Header", "r")) {
- X while (fgets(ScrBuf, sizeof(ScrBuf), fi)) {
- X SerPuts(ScrBuf);
- X SerPuts("\r");
- X }
- X fclose(fi);
- X }
- X termCr = termLf = 1;
- X SerPuts("Login: ");
- X ulog(-1, "Getty, Connect, Login");
- X State = ST_LOGIN;
- X Index = 0;
- X HaveLogin = 0;
- X LoginBuf[0] = 0;
- X }
- X break;
- X case ST_LOGIN: /* wait Login: response */
- X if (HaveLogin) {
- X if (LoginBuf[0] == 0) {
- X State = ST_CONNECT;
- X break;
- X }
- X ClearRecv();
- X PasswdBuf[0] = 0;
- X
- X /*
- X * If no password required, else request
- X * password.
- X */
- X
- X if (CheckLoginAndPassword()) {
- X HavePasswd = 1;
- X Index = 0;
- X State = ST_PASSWD;
- X } else {
- X SerPuts("Password: ");
- X ulog(1, "Getty, Passwd");
- X State = ST_PASSWD;
- X HavePasswd = 0;
- X Index = 0;
- X }
- X }
- X break;
- X case ST_PASSWD: /* wait Password: response */
- X if (HavePasswd) {
- X if (CheckLoginAndPassword()) {
- X ulog(-1, "login %s", LoginBuf);
- X
- X /*
- X * Disable read requests but leave serial
- X * port locked.
- X */
- X
- X if (IosrIP) {
- X AbortIO(&Iosr);
- X WaitIO(&Iosr);
- X IosrIP = 0;
- X }
- X
- X /*
- X * If run successful, leave read req and
- X * timer disabled.
- X */
- X
- X RunPasswdEntry();
- X
- X if (DropOnExit)
- X Disconnect(1);
- X else
- X State = ST_CONNECT;
- X ulog(-1, "disconnect");
- X } else {
- X SerPuts("Login Failed.\r\n\n");
- X State = ST_CONNECT;
- X ulog(-1, "LoginFailed user=%s pass=%s", LoginBuf, PasswdBuf);
- X }
- X HaveLogin = 0;
- X HavePasswd= 0;
- X LoginBuf[0] = 0;
- X }
- X break;
- X }
- X
- X /*
- X * Make no read requests while running 3rd party
- X * program, else resend read request.
- X */
- X
- X if (IotIP == 0) {
- X IotIP = 1;
- X SendIO(&Iot);
- X }
- X }
- X
- X /*
- X * RECEIVED SERIAL READ DATA
- X */
- X
- X if (ior == (IOR *)&Iosr) {
- X IosrIP = 0;
- X
- X Iosw.IOSer.io_Command = SDCMD_QUERY;
- X DoIO(&Iosw);
- X if (IgnoreCD)
- X Iosw.io_Status &= ~CIAF_COMCD;
- X
- X /*
- X * BREAK used to switch baud rates between allowed
- X * values
- X */
- X
- X if (Iosw.io_Status & IO_STATF_READBREAK) {
- X if (BaudAdjust == 0 && (State == ST_LOGIN || State == ST_PASSWD)) {
- X if (++BIndex == arysize(Bauds))
- X BIndex = 0;
- X if (Bauds[BIndex] == 0)
- X BIndex = 0;
- X Iosw.io_Baud = Bauds[BIndex];
- X SetParams(&Iosw);
- X if (Wire7)
- X Set7Wire(&Iosw);
- X ulog(1, "<BREAK> to %d baud", Iosw.io_Baud);
- X Delay(100);
- X ClearRecv();
- X Index = 0;
- X State = ST_CONNECT;
- X }
- X } else
- X if (Iosr.IOSer.io_Actual == 1) {
- X char *ptr;
- X UBYTE c = (UBYTE)RxBuf[0];
- X
- X ulog(2, "Rx %02x %c", c, (c < 32) ? ' ' : c);
- X c &= 0x7F;
- X
- X switch(State) {
- X case ST_WAITCD: /* looking for CONNECT msg */
- X case ST_CONNECT: /* looking for CONNECT msg */
- X ptr = ConnectBuf;
- X break;
- X case ST_LOGIN: /* looking for login name */
- X ptr = LoginBuf;
- X break;
- X case ST_PASSWD: /* looking for password */
- X ptr = PasswdBuf;
- X break;
- X }
- X if (State == ST_LOGIN && HaveLogin)
- X c = 0;
- X if (State == ST_PASSWD && HavePasswd)
- X c = 0;
- X
- X switch(c) {
- X case 0:
- X break;
- X case 8:
- X if (State == ST_LOGIN && HaveLogin)
- X break;
- X if (Index) {
- X if (State == ST_LOGIN)
- X SerPuts("\010 \010");
- X --Index;
- X }
- X break;
- X case 10:
- X if (termLf == 0)
- X break;
- X termCr = 0;
- X case 13:
- X if (c == 13) {
- X if (termCr == 0)
- X break;
- X else
- X termLf = 0;
- X }
- X ptr[Index] = 0;
- X Index = 0;
- X switch(State) {
- X case ST_WAITCD:
- X case ST_CONNECT:
- X if (strncmp(ptr, "CONNECT", 7)) {
- X ulog(1, "Looking for CONNECT, got '%s'", ptr);
- X break;
- X }
- X Delay(50);
- X HaveConnectMsg = 1;
- X if (BaudAdjust) {
- X ulog(-1, "Connect Auto-Baud %d", Iosw.io_Baud);
- X } else {
- X char *str = ptr + 7;
- X while (*str && (*str == 9 || *str == ' '))
- X ++str;
- X if (*str >= '0' && *str <= '9')
- X Iosw.io_Baud = atoi(str);
- X else
- X Iosw.io_Baud = Bauds[0];
- X SetParams(&Iosw);
- X ulog(-1, "Connect at %d baud", Iosw.io_Baud);
- X }
- X if (Wire7)
- X Set7Wire(&Iosw);
- X break;
- X case ST_LOGIN:
- X HaveLogin = 1;
- X SerPuts("\r\n");
- X ulog(1, "Login: %s", ptr);
- X break;
- X case ST_PASSWD:
- X HavePasswd = 1;
- X SerPuts("\r\n");
- X ulog(1, "Password: %s", ptr);
- X break;
- X }
- X break;
- X default:
- X if (Index == 31)
- X break;
- X if (State == ST_LOGIN) {
- X char cc[2];
- X cc[0] = c;
- X cc[1] = 0;
- X SerPuts(cc);
- X }
- X ptr[Index++] = c;
- X break;
- X }
- X }
- X if (IosrIP == 0) {
- X Iosr.IOSer.io_Command = CMD_READ;
- X Iosr.IOSer.io_Data = (APTR)RxBuf;
- X Iosr.IOSer.io_Length = 1;
- X SendIO(&Iosr);
- X IosrIP = 1;
- X }
- X }
- X }
- X }
- X xexit(0);
- X}
- X
- Xvoid
- XSerialOff()
- X{
- X if (IosrIP) {
- X AbortIO(&Iosr);
- X WaitIO(&Iosr);
- X IosrIP = 0;
- X }
- X if (Locked) {
- X UnLockSerialPort(DeviceName, DeviceUnit);
- X Locked = 0;
- X ulog(1, "Serial Port UnLocked");
- X }
- X}
- X
- Xvoid
- Xxexit(code)
- X{
- X if (ComPortMask) {
- X GMsg *msg;
- X Forbid();
- X while (msg = (GMsg *)GetMsg(ComPort))
- X ReplyMsg((MSG *)msg);
- X DeletePort(ComPort);
- X Permit();
- X }
- X if (IotIP) {
- X AbortIO(&Iot);
- X WaitIO(&Iot);
- X }
- X if (Iot.tr_node.io_Device)
- X CloseDevice(&Iot);
- X
- X if (IosrIP) {
- X AbortIO(&Iosr);
- X WaitIO(&Iosr);
- X }
- X if (Iosr.IOSer.io_Device) {
- X RestoreDeviceVector(Iosr.IOSer.io_Device);
- X CloseDevice(&Iosr);
- X }
- X
- X if (IoSink)
- X DeletePort(IoSink);
- X
- X if (NullFH)
- X Close(NullFH);
- X
- X if (Locked)
- X UnLockSerialPort(DeviceName, DeviceUnit);
- X
- X exit(code);
- X}
- X
- Xvoid
- XSerPuts(str)
- Xchar *str;
- X{
- X Iosw.IOSer.io_Command = CMD_WRITE;
- X Iosw.IOSer.io_Data = (APTR)str;
- X Iosw.IOSer.io_Length = strlen(str);
- X DoIO(&Iosw);
- X}
- X
- Xstatic short RxDisableIP;
- X
- Xvoid
- XRxDisable()
- X{
- X RxDisableIP = IosrIP;
- X if (IosrIP) {
- X AbortIO(&Iosr);
- X WaitIO(&Iosr);
- X IosrIP = 0;
- X }
- X}
- X
- Xvoid
- XRxEnable()
- X{
- X if (RxDisableIP && IosrIP == 0) {
- X Iosr.IOSer.io_Command = CMD_READ;
- X Iosr.IOSer.io_Data = (APTR)RxBuf;
- X Iosr.IOSer.io_Length = 1;
- X SendIO(&Iosr);
- X IosrIP = 1;
- X }
- X}
- X
- Xvoid
- XClearRecv()
- X{
- X RxDisable();
- X ulog(1, "Clear beg");
- X for (;;) {
- X Iosr.IOSer.io_Command = SDCMD_QUERY;
- X DoIO(&Iosr);
- X if ((Iosr.IOSer.io_Length = Iosr.IOSer.io_Actual) <= 0)
- X break;
- X if (Iosr.IOSer.io_Length > sizeof(RxBuf))
- X Iosr.IOSer.io_Length = sizeof(RxBuf);
- X Iosr.IOSer.io_Data = (APTR)RxBuf;
- X Iosr.IOSer.io_Command = CMD_READ;
- X DoIO(&Iosr);
- X }
- X ulog(1, "Clear end");
- X RxEnable();
- X}
- X
- Xvoid
- XSetParams(ior)
- XIOSER *ior;
- X{
- X int error;
- X
- X if (IosrIP)
- X AbortIO(&Iosr);
- X ior->IOSer.io_Command = SDCMD_SETPARAMS;
- X error = DoIO(ior);
- X if (error)
- X printf("SetParams, error %d\n", error);
- X}
- X
- Xvoid
- XSet7Wire(ior)
- XIOSER *ior;
- X{
- X short error;
- X
- X if (IosrIP)
- X AbortIO(&Iosr);
- X ior->IOSer.io_Command = SDCMD_SETPARAMS;
- X ior->io_SerFlags |= SERF_7WIRE;
- X error = DoIO(ior);
- X ior->io_SerFlags &= ~SERF_7WIRE;
- X if (error)
- X printf("SetParams, error %d\n", error);
- X}
- X
- Xvoid
- XDisconnect(dropdtr)
- X{
- X short retry = (IgnoreDTR) ? 2 : 10;
- X
- X ulog(1, "Disconnect drop=%d", dropdtr);
- X HaveConnectMsg = 0;
- X HaveLogin = 0;
- X HavePasswd = 0;
- X LoginBuf[0] = 0;
- X PasswdBuf[0] = 0;
- X Index = 0;
- X State = ST_WAITCD;
- X
- X while (dropdtr && DeviceInUse() == 0) {
- X short i;
- X
- X RxDisable();
- X
- X if (IgnoreDTR) {
- X if (ModemType != 'd') {
- X Delay(70);
- X SerPuts("+++");
- X Delay(70);
- X SerPuts("\010\010\r");
- X Delay(10);
- X SerPuts("ATH0\r");
- X Delay(120);
- X }
- X } else {
- X CloseDevice(&Iosr);
- X Iosr.IOSer.io_Device = NULL; /* so xexit doesn't reclose */
- X for (i = 0; i < 5; ++i) { /* 5 seconds */
- X Delay(50);
- X if (SetSignal(SIGBREAKF_CTRL_C, 0) & SIGBREAKF_CTRL_C)
- X xexit(23);
- X }
- X
- X /*
- X * Use Iosr to re-open serial device so we don't loose
- X * our config.
- X */
- X
- X if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0)) {
- X Iosr.IOSer.io_Device = NULL;
- X xexit(22);
- X }
- X Iosw.IOSer.io_Device = Iosr.IOSer.io_Device;
- X Iosw.IOSer.io_Unit = Iosr.IOSer.io_Unit;
- X SetParams(&Iosw);
- X }
- X
- X /*
- X * Loop until carrier lost
- X */
- X
- X Iosw.IOSer.io_Command = SDCMD_QUERY;
- X DoIO(&Iosw);
- X if (IgnoreCD)
- X Iosw.io_Status &= ~CIAF_COMCD;
- X
- X RxEnable();
- X
- X if ((Iosw.io_Status & CIAF_COMCD) != 0)
- X break;
- X if (--retry == 0) {
- X if (IgnoreDTR == 0)
- X puts("Getty: unable to disconnect!");
- X break;
- X }
- X }
- X if (DeviceInUse() == 0)
- X InitModem();
- X}
- X
- Xvoid
- XInitModem()
- X{
- X char buf[64];
- X short i;
- X
- X RxDisable();
- X ulog(1, "Init Modem");
- X Iosw.io_Baud = Bauds[0]; /* reset baud rate */
- X BIndex = 0;
- X SetParams(&Iosw);
- X RxEnable();
- X
- X switch(ModemType) {
- X case 'm': /* Multi Modem */
- X SerPuts("\010\010\r");
- X Delay(10);
- X SerPuts("AT\r");
- X Delay(50);
- X sprintf(buf, "ATM%dS0=%dX4$BA%d&E%d\r",
- X SpeakerLevel,
- X AnswerRing,
- X !BaudAdjust,
- X (Wire7) ? 4 : 3
- X );
- X SerPuts(buf);
- X break;
- X case 'h':
- X SerPuts("\010\010\r");
- X Delay(10);
- X SerPuts("ATZ\r");
- X Delay(120);
- X strcpy(buf, "AT");
- X if (SpeakerOpt)
- X sprintf(buf + strlen(buf), "M%d", SpeakerLevel);
- X sprintf(buf + strlen(buf), "S0=%d", AnswerRing);
- X strcat(buf, "\r");
- X SerPuts(buf);
- X break;
- X case 'd':
- X SerPuts("\010\010\r");
- X break;
- X }
- X for (i = 0; i < arysize(AtFields) && AtFields[i]; ++i) {
- X Delay(50);
- X SerPuts(AtFields[i]);
- X SerPuts("\r");
- X }
- X Delay(20);
- X ClearRecv();
- X Index = 0;
- X}
- X
- Xvoid
- XDoOptions(ac, av)
- Xchar *av[];
- X{
- X short i;
- X short bi = 0;
- X short fi = 0;
- X long v;
- X
- X for (i = 1; i < ac; ++i) {
- X char *ptr = av[i];
- X if (*ptr != '-') {
- X if (fi != arysize(AtFields))
- X AtFields[fi++] = ptr;
- X else
- X puts("AT field overflow");
- X continue;
- X }
- X if (*++ptr) /* skip - */
- X ++ptr; /* and option */
- X v = atoi(ptr);
- X switch(ptr[-1]) {
- X case '0':
- X ZeroOption = 1;
- X break;
- X case '7':
- X Wire7 = 1;
- X break;
- X case 'S':
- X DeviceName = ptr;
- X break;
- X case 'U':
- X DeviceUnit = v;
- X break;
- X case 'M':
- X ModemType = *ptr;
- X break;
- X case 'A':
- X BaudAdjust = 1;
- X break;
- X case 'B':
- X if (bi != arysize(Bauds))
- X Bauds[bi++] = v;
- X else
- X puts("-B field overflow");
- X break;
- X case 'm':
- X SpeakerOpt = 1;
- X SpeakerLevel = v;
- X break;
- X case 'r':
- X AnswerRing = v;
- X break;
- X case 'h':
- X IgnoreCD = !v;
- X break;
- X case 'c':
- X IgnoreConnect = !v;
- X break;
- X case 'd':
- X IgnoreDTR = !v;
- X break;
- X case 'x':
- X LogLevel = v;
- X LogToStdout = (v >= 0);
- X break;
- X default:
- X printf("Warning, Bad option: -%s\n", ptr);
- X break;
- X }
- X }
- X if (fi && fi != arysize(AtFields))
- X AtFields[fi] = NULL;
- X if (bi && bi != arysize(Bauds))
- X Bauds[bi] = 0;
- X}
- X
- XDeviceInUse()
- X{
- X return(Iosr.IOSer.io_Device->dd_Library.lib_OpenCnt > 1);
- X}
- X
- X/*
- X * Device Vector Intercept, used to force SERF_SHARED on device open.
- X */
- X
- Xextern void AsmIntercept();
- Xextern void AsmRoute();
- XFPTR OldVector;
- X
- Xvoid
- XInterceptDeviceVector(dev)
- Xstruct Device *dev;
- X{
- X OldVector = SetFunction((struct Library *)dev, LIB_OPEN, AsmIntercept);
- X AsmRoute(OldVector);
- X}
- X
- Xvoid
- XRestoreDeviceVector(dev)
- Xstruct Device *dev;
- X{
- X SetFunction((struct Library *)dev, LIB_OPEN, OldVector);
- X}
- X
- X
- END_OF_FILE
- if test 20766 -ne `wc -c <'uucp2/src/getty/getty.c'`; then
- echo shar: \"'uucp2/src/getty/getty.c'\" unpacked with wrong size!
- fi
- # end of 'uucp2/src/getty/getty.c'
- fi
- if test -f 'uucp2/src/uucico/gio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'uucp2/src/uucico/gio.c'\"
- else
- echo shar: Extracting \"'uucp2/src/uucico/gio.c'\" \(18871 characters\)
- sed "s/^X//" >'uucp2/src/uucico/gio.c' <<'END_OF_FILE'
- X
- X/*
- X * GIO.C WINDOWED G PROTOCOL
- X *
- X * written from scratch, except the checksum routine which was
- X * rewritten but based on the old one.
- X *
- X * WINDOW SIZE: When changing the window size be sure there
- X * are enough buffers available for pending txs.
- X *
- X * GIO.C (c)Copyright 1989, Matthew Dillon, All Rights Reserved
- X * extended to window size of 7 by Jack J. Rouse
- X */
- X
- X#include "includes.h"
- X
- Xtypedef unsigned char ubyte;
- Xtypedef unsigned short uword;
- X
- Xtypedef struct {
- X ubyte Dle; /* Literal ASCII DLE */
- X ubyte K; /* data size 2^(K+4) except K=0 means no data */
- X ubyte CL,CH; /* MAGIC - chksum(data) ^ C */
- X ubyte C;
- X ubyte X; /* K ^ C0 ^ C1 ^ C */
- X} Frame;
- X
- Xtypedef struct {
- X ubyte CType; /* bits 7-6 of C */
- X ubyte CCmd; /* bits 5-3 of C */
- X ubyte CSeq; /* bits 2-0 of C */
- X ubyte PLen; /* pre-data (2 bytes) for SHORTDATA type */
- X ubyte *Data; /* implies CType=LONGDATA or SHORTDATA */
- X uword DLen; /* length of data */
- X} Packet;
- X
- XPrototype int gwrdata(FILE *);
- XPrototype int gwrmsg(char *);
- XPrototype int grddata(FILE *);
- XPrototype int grdmsg(char *, int);
- XPrototype int gturnon(int);
- XPrototype int gturnoff(void);
- XPrototype void ResetGIO(void);
- X
- XLocal char *GetTxBuf(void);
- XLocal int SendDataPacket(unsigned char *, int);
- XLocal int RecvDataPacket(char **);
- XLocal int GetData(int, Packet *);
- XLocal int RecvdAck(char);
- XLocal int WriteCtlPacket(int);
- XLocal int WritePacket(Packet *, int);
- XLocal int ReadPacket(Packet *, int);
- XLocal int CheckSum(unsigned char *, int);
- XLocal void FrameToPacket(Frame *, Packet *, unsigned char *);
- XLocal int LenToK(unsigned short);
- X
- Xextern int debug;
- Xextern int WindowOne;
- X
- X#define SUCCESS 0
- X#define FAIL 1
- X
- X#define MAGIC 0125252
- X#define DLE 0x10
- X#define WINDOWSIZE 7
- X#define SEGSIZEK 2 /* 64 bytes ?? */
- X
- X#define SUB1(var) (((var)-1)&7)
- X
- X
- X#define CT_CONTROL (0 << 6)
- X#define CT_ALTCHN (1 << 6)
- X#define CT_LONGDATA (2 << 6)
- X#define CT_SHORTDATA (3 << 6)
- X#define CT_MASK (3 << 6)
- X
- X#define CC_CLOSE (1 << 3)
- X#define CC_RJ (2 << 3)
- X#define CC_SRJ (3 << 3)
- X#define CC_RR (4 << 3)
- X#define CC_INITC (5 << 3)
- X#define CC_INITB (6 << 3)
- X#define CC_INITA (7 << 3)
- X#define CC_MASK (7 << 3)
- X
- X#define SEQ_MASK 7
- X
- X#define WAIT_ACK 1
- X#define WAIT_DATA 2
- X#define WAIT_CONTROL 3
- X
- X#define MaxPktSize 4096
- X
- Xchar RxBuf[MaxPktSize+4];
- Xchar *TxBuf[8];
- X
- X /* TRANSMIT STAGE */
- Xchar TxSeq = 0; /* Last send packet */
- Xchar TxPend= 0; /* hasn't been acked yet */
- Xuword TxWinSize; /* 1 or 2 (max 7) */
- Xuword TxSegSize; /* maximum segment size */
- Xchar TxSegK; /* K for TxSegSize */
- XPacket TxPacket[8]; /* contents of last packet */
- X
- X /* RECEIVE STAGE */
- Xchar RxSeq = 0; /* Last valid recv pkt */
- Xchar RxRdy = 0; /* Has come in.. */
- Xchar RxRetry = 8;
- Xchar RxNotAcked = 0; /* We have yet to ack it */
- XPacket RxPacket; /* The packet that has come in */
- X
- Xvoid
- XResetGIO()
- X{
- X TxSeq = 0;
- X TxPend= 0;
- X TxWinSize = 0;
- X TxSegSize = 0;
- X TxSegK = 0;
- X RxSeq = 0;
- X RxRdy = 0;
- X RxRetry = 8;
- X RxNotAcked = 0;
- X}
- X
- X/*
- X * Get Transmit Buffer. Note that some space to the left is available
- X */
- X
- XLocal
- Xchar *
- XGetTxBuf()
- X{
- X static int index = 0;
- X
- X if (++index > TxWinSize)
- X index = 0;
- X if (TxBuf[index] == NULL
- X && (TxBuf[index] = (char *)malloc(MaxPktSize+4)) == NULL)
- X {
- X printf("Out of memory in GetTxBuf.");
- X /* could handle this case better, but it should be rare */
- X xexit(1);
- X }
- X return(TxBuf[index] + 2);
- X}
- X
- Xint
- Xgwrdata(fi)
- XFILE *fi;
- X{
- X int bytes;
- X
- X if (debug > 7)
- X printf("GWRDATA: ");
- X
- X for (;;) {
- X char *buf = GetTxBuf();
- X if ((bytes = fread(buf, 1, TxSegSize, fi)) <= 0)
- X break;
- X if (SendDataPacket(buf, bytes) != SUCCESS) {
- X if (debug > 7)
- X printf("GWR Failed\n");
- X return(FAIL);
- X }
- X if (debug > 7)
- X printf("\nGWROK ");
- X }
- X {
- X char *buf = GetTxBuf();
- X if (SendDataPacket(buf, 0) != SUCCESS) {
- X if (debug > 7)
- X printf("GWR Failed (last)\n");
- X return(FAIL);
- X }
- X }
- X if (debug > 7)
- X printf("\nGWFile Last Ack\n");
- X while (TxPend) {
- X if (GetData(WAIT_ACK, NULL) == FAIL)
- X return(FAIL);
- X }
- X if (debug > 7)
- X printf("success\n");
- X return (SUCCESS);
- X}
- X
- X/*
- X * Write message to the other guy.
- X *
- X * NOTE: LONGDATA packets used exclusively and \0 fill to end.
- X */
- X
- Xint
- Xgwrmsg(str)
- Xchar *str;
- X{
- X int len = strlen(str) + 1; /* type + str + \0 */
- X
- X if (debug > 7)
- X printf("GWRMSG: %s\n", str);
- X
- X while (len > TxSegSize) {
- X char *buf = GetTxBuf();
- X movmem(str, buf, TxSegSize);
- X if (debug > 7)
- X printf("GWR-SEND %d\n", TxSegSize);
- X if (SendDataPacket(buf, TxSegSize) != SUCCESS)
- X return(FAIL);
- X len -= TxSegSize;
- X str += TxSegSize;
- X }
- X
- X /*
- X * Find optimal packet size (remember, we must force LONGDATA
- X *
- X * Apparently packet sizes less than the agreed upon size are
- X * not allowed ???
- X */
- X
- X {
- X short siz = TxSegSize;
- X char *buf = GetTxBuf();
- X#ifdef NOTDEF
- X short k = TxSegK;
- X
- X while (k > 1 && (siz >> 1) >= len) {
- X --k;
- X siz >>= 1;
- X }
- X#endif
- X if (debug > 7)
- X printf("GWR-FNL %d %d\n", len, siz);
- X
- X movmem(str, buf, len);
- X setmem(buf + len, siz - len, 0);
- X if (SendDataPacket(buf, siz) != SUCCESS) {
- X if (debug > 7)
- X printf("GWR-FAIL\n");
- X return(FAIL);
- X }
- X }
- X if (debug > 7)
- X printf("GWR Last Ack\n");
- X while (TxPend) {
- X if (GetData(WAIT_ACK, NULL) == FAIL)
- X return(FAIL);
- X }
- X if (debug > 7)
- X printf("success\n");
- X return (SUCCESS);
- X}
- X
- Xint
- Xgrddata(fi)
- XFILE *fi;
- X{
- X int bytes;
- X char *buf;
- X
- X if (debug > 7)
- X printf("GRDDATA\n");
- X while ((bytes = RecvDataPacket(&buf)) > 0) {
- X if (debug > 7)
- X printf("GRDDATA blk %d\n", bytes);
- X fwrite(buf, 1, bytes, fi);
- X }
- X if (debug > 7)
- X printf("GRDDATA end %d\n", bytes);
- X if (bytes < 0)
- X return(FAIL);
- X else
- X return(SUCCESS);
- X}
- X
- Xint
- Xgrdmsg(buf, maxlen)
- Xchar *buf;
- X{
- X short i;
- X short n;
- X short slen;
- X char *ptr;
- X
- X i = 0;
- X if (debug > 7)
- X printf("GRDMSG\n");
- X while ((n = RecvDataPacket(&ptr)) > 0) {
- X ptr[n] = 0;
- X slen = strlen(ptr);
- X if (slen > maxlen - 1) {
- X printf("GRDMSG: Buffer overflow!\n");
- X return (FAIL);
- X }
- X movmem(ptr, buf + i, slen);
- X buf[i + slen] = 0;
- X if (slen != n)
- X break;
- X i += slen;
- X maxlen -= slen;
- X }
- X if (debug > 7)
- X printf("GRDMSGEND %d (%d) %s\n", n, i, buf);
- X if (n < 0) {
- X buf[0] = 0;
- X return(FAIL);
- X }
- X return(SUCCESS);
- X}
- X
- XLocal
- Xint
- XSendDataPacket(buf, bytes)
- Xubyte *buf;
- Xint bytes;
- X{
- X Packet P;
- X
- X /*
- X * If window exhausted we must wait for at least one ack.
- X */
- X
- X while (TxPend == TxWinSize) {
- X if (GetData(WAIT_ACK, NULL) == FAIL)
- X return(FAIL);
- X }
- X
- X TxSeq = (TxSeq + 1) & 7; /* next Tx packet */
- X
- X /*
- X * Figure out best fit packet size. Apparently packets smaller
- X * then the agreed upon size are not allowed ???
- X */
- X
- X#ifdef NOTDEF
- X {
- X short k = TxSegK;
- X P.DLen = TxSegSize;
- X while (k > 1 && P.DLen && (P.DLen >> 1) >= bytes) {
- X --k;
- X P.DLen >>= 1;
- X }
- X }
- X#else
- X P.DLen = TxSegSize;
- X#endif
- X
- X if (bytes < P.DLen) {
- X uword extra = P.DLen - bytes;
- X setmem(buf + bytes, extra, 0);
- X if (extra <= 127) {
- X P.PLen = 1;
- X buf[-1] = extra;
- X } else {
- X P.PLen = 2;
- X buf[-2] = 0x80 | extra;
- X buf[-1] = (extra >> 7);
- X }
- X P.CType = CT_SHORTDATA;
- X } else {
- X P.PLen = 0;
- X P.CType = CT_LONGDATA;
- X }
- X P.CCmd = TxSeq << 3; /* transmit sequence number */
- X P.CSeq = RxSeq; /* last valid received pkt */
- X P.Data = buf;
- X
- X if (debug > 7)
- X printf("WRITE DATA PACKET txseq=%d rxack=%d\n", TxSeq, P.CSeq);
- X
- X RxNotAcked = 0; /* We've acked the rx packet */
- X
- X TxPacket[TxSeq] = P;
- X ++TxPend;
- X
- X WritePacket(&TxPacket[TxSeq], 1);
- X
- X return(SUCCESS);
- X}
- X
- XLocal
- Xint
- XRecvDataPacket(pbuf)
- Xchar **pbuf;
- X{
- X if (RxRdy == 0) {
- X if (GetData(WAIT_DATA, NULL) != SUCCESS)
- X return(-1);
- X }
- X *pbuf = RxPacket.Data;
- X RxRdy = 0;
- X return((int)RxPacket.DLen);
- X}
- X
- Xint
- Xgturnon(master)
- Xint master;
- X{
- X Packet P;
- X short retry = 5;
- X short windowsize = WINDOWSIZE; /* our prefered window size */
- X short segsize = SEGSIZEK; /* our prefered segment size */
- X
- X if (WindowOne)
- X windowsize = 1;
- X
- X if (master) {
- X while (retry > 0) {
- X WriteCtlPacket(CC_INITA | windowsize);
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
- X if (P.CSeq && P.CSeq < windowsize)
- X windowsize = P.CSeq;
- X break;
- X }
- X --retry;
- X }
- X while (retry > 0) {
- X WriteCtlPacket(CC_INITB | (segsize - 1));
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
- X if (P.CSeq < segsize - 1)
- X segsize = P.CSeq + 1;
- X break;
- X }
- X --retry;
- X }
- X while (retry > 0) {
- X WriteCtlPacket(CC_INITC | windowsize);
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
- X if (P.CSeq && P.CSeq < windowsize)
- X windowsize = P.CSeq;
- X break;
- X }
- X --retry;
- X }
- X } else {
- X while (retry > 0) {
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
- X WriteCtlPacket(CC_INITA | windowsize);
- X if (P.CSeq && windowsize > P.CSeq)
- X windowsize = P.CSeq;
- X break;
- X }
- X --retry;
- X }
- X while (retry > 0) {
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
- X WriteCtlPacket(CC_INITB | (segsize - 1));
- X if (P.CSeq < segsize - 1)
- X segsize = P.CSeq + 1;
- X break;
- X }
- X --retry;
- X }
- X while (retry > 0) {
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
- X WriteCtlPacket(CC_INITC | windowsize);
- X if (P.CSeq && windowsize > P.CSeq)
- X windowsize = P.CSeq;
- X break;
- X }
- X --retry;
- X }
- X }
- X TxSegK = segsize;
- X TxSegSize = 1 << (TxSegK + 4);
- X TxWinSize = windowsize;
- X if (debug > 0)
- X printf("Window Size is %d\n", TxWinSize);
- X if (retry == 0)
- X return(FAIL);
- X return(SUCCESS);
- X}
- X
- Xint
- Xgturnoff()
- X{
- X Packet P;
- X
- X WriteCtlPacket(CC_CLOSE);
- X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_CLOSE) {
- X WriteCtlPacket(CC_RR | RxSeq);
- X return (SUCCESS);
- X }
- X return (FAIL);
- X}
- X
- X/*
- X * GetData()
- X *
- X * This is the core of the packet protocol. As soon as we get a satisfactory
- X * terminating condition we return. However, on unsatisfactory conditions
- X * such as having to send a reject, we attempt to drain any pending data
- X * (i.e. multiple returned rejects) so we do not do multiple resends.
- X *
- X * The resend flag only applies on a failure return.
- X */
- X
- XLocal
- Xint
- XGetData(waitfor, p)
- Xint waitfor;
- XPacket *p;
- X{
- X Packet P;
- X short timeout;
- X short drainmode = 0;
- X
- X /*
- X * If we haven't acked the last packet we received we must do
- X * so now before we can expect to receive another one!
- X */
- X
- X if (debug > 7)
- X printf("Get-Data waitfor %s\n", (waitfor == WAIT_ACK) ? "WAIT_ACK" : "WAIT_DATA");
- X if (waitfor == WAIT_ACK)
- X timeout = 5;
- X else if (waitfor == WAIT_DATA)
- X timeout = 20;
- X else
- X timeout = 20;
- X
- X for (;;) {
- X if (RxNotAcked) { /* good, send ack for rx'd pkt */
- X WriteCtlPacket(CC_RR | RxSeq);
- X RxNotAcked = 0;
- X } /* bad, timeout on read */
- X if (ReadPacket(&P, (drainmode) ? 0 : timeout) == FAIL) {
- X drainmode = 0;
- X
- X /*
- X * If we have timed out waiting for data then send a reject
- X */
- X
- X if (waitfor == WAIT_DATA) {
- X if (RxRetry) {
- X --RxRetry;
- X if (debug > 7)
- X printf("\nWAIT-DATA, TIMEOUT, SEND RJ\n");
- X WriteCtlPacket(CC_RJ | RxSeq);
- X continue;
- X }
- X }
- X
- X /*
- X * If we have timed out waiting for an ack send the entire
- X * window. We must send the window sometime and it might as
- X * well be now.
- X */
- X
- X if (waitfor == WAIT_ACK) {
- X if (RxRetry) {
- X int i;
- X
- X if (debug > 7)
- X printf("RESEND %d packets\n", TxPend);
- X for (i = 1; i <= TxPend; ++i) {
- X Packet *p = &TxPacket[(TxSeq - TxPend + i) & 7];
- X p->CSeq = RxSeq;
- X WritePacket(p, 1);
- X }
- X --RxRetry;
- X continue;
- X }
- X }
- X if (debug > 7)
- X printf("COMPLETE FAILURE RxRetry = %d\n", RxRetry);
- X return(FAIL);
- X }
- X
- X /*
- X * valid packet, terminating condition?
- X */
- X
- X RxRetry = 8;
- X switch(P.CType) {
- X case CT_CONTROL:
- X switch(P.CCmd) {
- X case CC_CLOSE: /* End of communication ... not an ACK! */
- X if (waitfor == WAIT_CONTROL) {
- X *p = P;
- X return(SUCCESS);
- X }
- X return(FAIL);
- X case CC_RJ: /* Reject packet (P.CSeq == last good packet) */
- X (void)RecvdAck(P.CSeq);
- X drainmode = 1;
- X break;
- X case CC_SRJ: /* Selective Reject (P.CSeq == bad packet # ) */
- X return(FAIL);
- X case CC_RR: /* Ack to packet (P.CSeq == packet # acked) */
- X#ifdef NOTDEF
- X if (P.CSeq == ((TxSeq - TxPend) & 7)) {
- X /*
- X * The CSeq packet was previously acknowledged
- X * The receiver apparently has not seen anything since.
- X * This is the same as a rejection.
- X */
- X goto resend;
- X }
- X#endif
- X if (RecvdAck(P.CSeq) == SUCCESS && waitfor == WAIT_ACK)
- X return(SUCCESS);
- X break;
- X case CC_INITC:
- X case CC_INITB:
- X case CC_INITA:
- X if (waitfor == WAIT_CONTROL) {
- X *p = P;
- X return(SUCCESS);
- X }
- X return(FAIL);
- X }
- X break;
- X case CT_ALTCHN:
- X printf("ALTCHN packet ??\n");
- X break;
- X case CT_LONGDATA:
- X case CT_SHORTDATA:
- X {
- X char rxseq = P.CCmd >> 3;
- X char txack = P.CSeq;
- X
- X if (RxRdy == 1) {
- X printf("Got two receive packets without me acking!\n");
- X }
- X
- X if (rxseq == RxSeq) { /* already got this packet */
- X RxNotAcked = 1;
- X continue;
- X /* expected packet? */
- X } else if (rxseq != ((RxSeq + 1) & 7)) {
- X drainmode = 1;
- X printf("Received sequence %d, expected %d\n", rxseq, (RxSeq + 1) & 7);
- X break;
- X }
- X if (debug > 6)
- X printf("RECV SEQUENCE %d\n", rxseq);
- X
- X RecvdAck(txack); /* woa */
- X
- X /*
- X * Delay sending the ACK back in case we can combine
- X * it with the next transmitted packet.
- X */
- X
- X RxNotAcked = 1; /* we haven't ack'd the rx packet */
- X
- X RxSeq = (RxSeq + 1) & 7;
- X RxRdy = 1;
- X RxPacket = P;
- X if (waitfor == WAIT_DATA)
- X return(SUCCESS);
- X if (TxPend == 0 && waitfor == WAIT_ACK)
- X return(SUCCESS);
- X }
- X break;
- X }
- X }
- X}
- X
- XLocal
- Xint
- XRecvdAck(seq)
- Xchar seq;
- X{
- X short i;
- X
- X /*
- X * which packet was acked?
- X */
- X
- X for (i = 0; i < TxPend; ++i) {
- X if (seq == ((TxSeq - i) & 7))
- X break;
- X }
- X if (i && i == TxPend) {
- X if (seq != ((TxSeq - TxPend) & 7))
- X printf("He acked the wrong packet! %d expected %d\n", seq, TxSeq);
- X return(FAIL);
- X }
- X if (debug > 7)
- X printf("TxPend %d -> %d\n", TxPend, i);
- X TxPend = i;
- X return(SUCCESS);
- X}
- X
- XLocal
- Xint
- XWriteCtlPacket(cc)
- Xint cc;
- X{
- X Packet pk;
- X
- X pk.CType = CT_CONTROL;
- X pk.CCmd = cc & CC_MASK;
- X pk.CSeq = cc & SEQ_MASK;
- X pk.PLen = 0;
- X pk.DLen = 0;
- X WritePacket(&pk, 0);
- X return(SUCCESS);
- X}
- X
- XLocal
- Xint
- XWritePacket(pk, async)
- XPacket *pk;
- Xint async;
- X{
- X Frame F;
- X uword sum;
- X
- X F.Dle = DLE;
- X F.C = pk->CType | pk->CCmd | pk->CSeq;
- X F.K = 9;
- X
- X if (pk->CType == CT_SHORTDATA || pk->CType == CT_LONGDATA)
- X F.K = LenToK(pk->DLen);
- X else
- X pk->DLen = 0;
- X
- X sum = MAGIC - (CheckSum(pk->Data - pk->PLen, pk->DLen) ^ F.C);
- X
- X F.CH = sum >> 8;
- X F.CL = sum;
- X F.X = F.K ^ F.CH ^ F.CL ^ F.C;
- X
- X if (debug > 7)
- X printf("WritePacket: F.K = %d F.C = %d.%d.%d\n", F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
- X
- X if (async)
- X xwritea(&F, sizeof(F));
- X else
- X xwrite(&F, sizeof(F)); /* write header */
- X if (pk->DLen) { /* write data */
- X if (async)
- X xwritea(pk->Data - pk->PLen, pk->DLen);
- X else
- X xwrite(pk->Data - pk->PLen, pk->DLen);
- X }
- X return(SUCCESS);
- X}
- X
- XLocal
- Xint
- XReadPacket(pk, timeout)
- XPacket *pk;
- Xint timeout;
- X{
- X Frame F;
- X short c;
- X short i = 0;
- X
- X pk->Data = RxBuf;
- X pk->CType = 0xFF;
- X pk->CCmd = 0;
- X pk->CSeq = 0;
- X
- X if (debug > 7)
- X printf("ReadPacket\n");
- X while ((c = xgetc(timeout)) != EOF) {
- X if (debug > 8)
- X printf("RP %d %02x\n", i, c);
- X
- X switch(i) {
- X case 0:
- X if (c == DLE) {
- X F.Dle = c;
- X ++i;
- X if (timeout == 0)
- X timeout = 1;
- X }
- X break;
- X case 1:
- X F.K = c;
- X ++i;
- X if (c == DLE) { /* K only valid 1-9 */
- X F.Dle = c;
- X i = 1;
- X }
- X else if (c == 0 || c > 9)
- X i = 0;
- X break;
- X case 2:
- X F.CL = c;
- X ++i;
- X break;
- X case 3:
- X F.CH = c;
- X ++i;
- X break;
- X case 4:
- X F.C = c;
- X ++i;
- X break;
- X case 5:
- X F.X = c;
- X if (F.X != (F.K ^ F.CH ^ F.CL ^ F.C)) {
- X printf("F.X failed: %02x %02x\n", F.X, (F.K ^ F.CH ^ F.CL ^ F.C));
- X i = 0;
- X } else { /* get data segment if any */
- X ++i;
- X }
- X break;
- X }
- X if (i == 6)
- X break;
- X }
- X if (debug > 7) {
- X if (i)
- X printf("RP Hdr i = %d, F.K = %d F.C = %d.%d.%d\n", i, F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
- X else
- X printf("RP Hdr <rx timeout>\n");
- X }
- X
- X if (i == 6) { /* Receive Data Portion */
- X uword pktsize = 1 << (F.K + 4);
- X uword n;
- X
- X if (F.K == 9)
- X pktsize = 0;
- X
- X if (pktsize > MaxPktSize) {
- X printf("Protocol failure pktsize %d/%d/%d\n", pktsize, TxSegSize, MaxPktSize);
- X return (FAIL);
- X }
- X for (n = 0; n < pktsize; ++n) {
- X if ((c = xgetc(4)) == EOF)
- X break;
- X pk->Data[n] = c;
- X }
- X if (c != EOF) {
- X uword hissum;
- X uword oursum;
- X hissum = (F.CH << 8) | F.CL;
- X oursum = MAGIC - (CheckSum(pk->Data, pktsize) ^ F.C);
- X if (debug > 7)
- X printf("Got Data, checking: %04x %04x\n", hissum, oursum);
- X if (hissum == oursum) {
- X FrameToPacket(&F, pk, pk->Data);
- X return (SUCCESS);
- X }
- X } else {
- X FrameToPacket(&F, pk, pk->Data); /* mainly for pk->CType */
- X return (FAIL);
- X }
- X }
- X /*
- X * Timeout, retry?
- X */
- X return (FAIL);
- X}
- X
- XLocal
- Xint
- XCheckSum(s, n)
- Xubyte *s;
- Xint n;
- X{
- X uword sum;
- X uword x;
- X uword t;
- X
- X if (n == 0)
- X return(0);
- X sum = -1;
- X x = 0;
- X
- X while (n) {
- X if (sum & 0x8000)
- X sum = (sum << 1) | 1;
- X else
- X sum = (sum << 1);
- X
- X t = sum;
- X sum += *s++;
- X x += sum ^ n;
- X if (sum <= t)
- X sum ^= x;
- X --n;
- X }
- X return((int)sum);
- X}
- X
- XLocal
- Xvoid
- XFrameToPacket(fr, pk, data)
- XFrame *fr;
- XPacket *pk;
- Xubyte *data;
- X{
- X pk->CType = fr->C & CT_MASK;
- X pk->CCmd = fr->C & CC_MASK;
- X pk->CSeq = fr->C & SEQ_MASK;
- X switch(pk->CType) {
- X case CT_LONGDATA:
- X pk->DLen = 1 << (fr->K + 4);
- X break;
- X case CT_SHORTDATA:
- X pk->DLen = 1 << (fr->K + 4);
- X if (pk->Data[0] & 0x80) {
- X pk->DLen -= (pk->Data[0] & 0x7F) | (pk->Data[1] << 7);
- X if (pk->DLen < 0) {
- X printf("DLEN ERROR %d\n", pk->DLen);
- X pk->DLen = 0;
- X }
- X pk->Data += 2;
- X } else {
- X pk->DLen -= *pk->Data;
- X ++pk->Data;
- X }
- X break;
- X default:
- X pk->DLen = 0;
- X break;
- X }
- X}
- X
- XLocal
- Xint
- XLenToK(bytes)
- Xuword bytes;
- X{
- X uword n = 32;
- X uword k = 1;
- X
- X while (n < bytes) {
- X n <<= 1;
- X ++k;
- X }
- X if (k > 8) {
- X printf("Soft error, LenToK: %d %d %d\n", bytes, n, k);
- X k = 8;
- X }
- X return((int)k);
- X}
- X
- END_OF_FILE
- if test 18871 -ne `wc -c <'uucp2/src/uucico/gio.c'`; then
- echo shar: \"'uucp2/src/uucico/gio.c'\" unpacked with wrong size!
- fi
- # end of 'uucp2/src/uucico/gio.c'
- fi
- echo shar: End of archive 8 \(of 12\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
- Mail comments to the moderator at <amiga-request@cs.odu.edu>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-